from time import sleep

from selenium.common.exceptions import StaleElementReferenceException

from qturboframe.lib.webdriver.ie.webdriver import WebDriver

from qturboframe.lib.webdriver.remote.webelement import WebElement

from qturboframe.lib.utils.by import By

from BladeFerm.hui12_common.function import display_wait
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger
from qturboframe.public_ui.h_ui.msg_box import MsgBox as HuiMsgBox


class MsgBox(HuiMsgBox):

    def __init__(self, text=None, idname=None, father=None, timeout=5):
        if idname:
            super().__init__(idname, father, timeout)
        elif text and not idname:
            if not father:
                raise AttributeError('未定位元素，father参数不能为None！')
            if isinstance(father, WebDriver):
                self._driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self._driver = father._parent
                self.timeout = timeout
            else:
                raise AttributeError('father参数类型不正确！')
            # re_pop_window_class = r'v-transfer-dom'
            re_modal_class = r'h-modal-wrap'
            re_modal_hidden_class = r'h-modal-hidden'
            if isinstance(text, dict):
                pos, content = "h-modal-body", ''
                for k, v in text.items():
                    pos, content = 'h-modal-' + k, v
                    break
            else:
                pos, content = "h-modal-body", text
            xpath_express = f'//div[contains(@class,"{pos}")]//*[contains(text(),"{content}")]//' \
                            f'ancestor::div[contains(@class,"{re_modal_class}")]'
            times = 0
            while times < timeout*2:
                try:
                    # 获取所有有re_pop_window_class属性的div
                    pop_windows = father.find_elements_by_attribute('xpath', xpath_express, timeout=0.1)
                    if pop_windows and len(pop_windows) == 1:
                        self._element = pop_windows[0]
                        break
                    elif pop_windows and len(pop_windows) > 1:
                        # self._element = None
                        for child_ele in reversed(pop_windows):
                            target_ele_class = child_ele.get_attribute('class')
                            logger.debug(f'target_ele_class: {target_ele_class}')
                            if child_ele.is_displayed():
                                self._element = child_ele
                                logger.debug(f'_element: {self._element}')
                                break
                        # raise SeleniumError(f'xpath 表达式 {xpath_express} 找到了多个弹框，不唯一。请重新确认定位信息。')
                        times = times + 1
                        sleep(0.5)
                    else:
                        times = times + 1
                        sleep(0.5)
                        self._element = None
                except StaleElementReferenceException as msg:
                    logger.debug(str(msg))
                    times = times + 1
                    sleep(0.5)
                    self._element = None
            # else:
            #     self._element = None
        else:
            raise SeleniumError(f'text {text} 和 idname {idname} 不能同时为空！')

    def click_button(self, text="确定"):
        xpath = f'.//div[@class="h-modal-footer"]//button'
        # xpath = f'.//button[contains(text(),"{text}")]'
        button = self._element.find_element_by_attribute(By.XPATH, xpath, f'text:{text}')
        button.click()
        logger.info(f'点击 {text} 按钮')

    def cancel_exprot(self):
        cancel_btn = self.element.find_element_by_attribute(By.CSS_SELECTOR,
                                                            'div.h-modal-footer>div>button.h-btn', 'text:取消导出')
        cancel_btn.clear()

    def close_dialog(self):
        close_btn = self.element.find_element_by_attribute(By.CSS_SELECTOR,
                                                           'div.h-modal-footer>div>button.h-btn', 'text:关闭')
        close_btn.clear()

    def check_dispaly(self, exp_flag):
        '''
        判断元素状态是否显示
        :param exp_flag: bool类型。可以是一个表达式，例如： ui_expect.get('期望结果') == '是'
        :return:
        '''
        if self._element:
            div_attr = self._element.get_attribute('class').split(' ')
            if 'h-modal-hidden' in div_attr:
                flag = False
            else:
                flag = True
        else:
            flag = False
        if flag == exp_flag:
            logger.info(f'实际检查结果[{flag}]与期望状态[{exp_flag}]一致。')
            return True
        else:
            logger.error(f'实际检查结果[{flag}]与期望状态[{exp_flag}]不一致！')
            raise SeleniumError(f'实际检查结果[{flag}]与期望状态[{exp_flag}]不一致！')


    def check_body_text(self, ui_except):
        '''
        检查弹框中间的文本内容是否和期望的一致
        :param ui_except:
        :return:
        '''
        if self._element.exit():
            body_div = self.element.find_element_by_attribute(By.CSS_SELECTOR, 'div.h-modal-body')
            body_text = body_div.text
            if body_text == ui_except:
                logger.info(f'检查弹框文本内容 {ui_except} 通过。')
                return True
            else:
                logger.error(f'检查弹框文本内容 {ui_except} 失败!')
                raise SeleniumError(f'检查弹框文本内容 {ui_except} 失败！')
        else:
            logger.error(f'获取弹框，查找内容 {ui_except} 失败!')
            raise SeleniumError(f'获取弹框，查找内容 {ui_except} 失败!')

    def check_export_result(self, exp=True, timeout=30):
        res_flag = display_wait(idname={By.XPATH: '//div[@class="h-modal-wrap h-modal-nocopy"]'},
                                flag=5, timeout=timeout, dirver=self.element)
        logger.info(f'等待导出结果是：{res_flag}，超时时间为: {timeout}')
        if res_flag == exp:
            logger.info(f'导出结果 {res_flag} 与期望结果 {exp} 一致。')
            return True
        else:
            logger.error(f'导出结果 {res_flag} 与期望结果 {exp} 不一致！超时时间为: {timeout}')
            raise SeleniumError(f'导出结果 {res_flag} 与期望结果 {exp} 不一致！超时时间为: {timeout}')